home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / utilprn / hpdeskje.sit / HPDJet ƒ / PRER_Builder.Pas < prev    next >
Pascal/Delphi Source File  |  1989-04-02  |  15KB  |  560 lines

  1. { 02.04.1989  amn  (latest edit) }
  2.  
  3. {$U-}  {don't automatically include units}
  4.  
  5. PROGRAM PRER_Builder;
  6.  
  7. { A program to build printer resource files from DRVR, PACK, and CODE resources }
  8. { produced by LightspeedC. }
  9.  
  10. { Author(s):  Ari Mujunen (amn@hutcs.hut.fi). }
  11. { Authors:  Ari Mujunen (amn@hutcs.hut.fi) and Olli Arnberg (oar@hutcs.hut.fi). }
  12. { Copyright Ari Mujunen, Olli Arnberg 1989. }
  13. { You may redistribute this program together the HPDJ printer driver }
  14. { (=printer resource file, source files, documentation file(s),}
  15. { and the file 'Copyright and Source Offer') }
  16. { only _non-commercially_ and _in its entirety_. }
  17.  
  18. { Change history: }
  19. { Version  Date        Who  Why }
  20. { 0.0      17.11.1988  amn  Initial version. }
  21. {          18.11.1988  amn  Use of jump table header when producing PDEF resources. }
  22. { 1.0      20.11.1988  amn  HomeResFile returns 0 for system file (despite IM I-116). }
  23. {          26.11.1988  amn  Noticed that 'DRVR' 2 '.Print' in System file should not }
  24. {                           be changed.  Name in 'STR ' -8192 suffices. }
  25. {                           Accept files of type 'PRES' (as Imagewriter). }
  26. {          03.02.1989  amn  Setting Chooser package flag bits correctly. }
  27. {          02.04.1989  amn  Copyright notice. }
  28.  
  29.  
  30. {$T APPLP*8-}  {File type 'APPL', creator 'P*8-'}
  31. {$R PRER_Builder.Rsrc}  {identify resource file}
  32.  
  33. USES
  34.   MemTypes,
  35.   QuickDraw,
  36.   OSIntf,
  37.   ToolIntf,
  38.   PackIntf;
  39.  
  40.  
  41.   CONST
  42.     { Resource id's: }
  43.     mainDLOGId = 128;
  44.     fileErrorALRTId = 128;
  45.     pdefCodeResourceHeaderHEADId = 128;
  46.     
  47.     resIdOwnedByPDEF = -8192;
  48.     resIdOwnedByPACK = -4096;
  49.     
  50.     okButton = 1;
  51.     cancelButton = 2;
  52.   
  53.   
  54.   VAR
  55.     applicationResFile: Integer;
  56.     actualSystemResFile: Integer;
  57.         
  58.     mainDialog: DialogPtr;
  59.     itemHit: Integer;
  60.     whatToDo:
  61.       RECORD
  62.         rFilePrefix: Str255;
  63.         rDrvr: Boolean;
  64.         rPdef0: Boolean;
  65.         rPdef1: Boolean;
  66.         rPdef4: Boolean;
  67.         rPdef5: Boolean;
  68.         rPack: Boolean;
  69.         rInstallToSystem: Boolean;
  70.         rPrinterResourceFile: SFReply;
  71.       END;
  72.     
  73.     printerResourceFileRefNum: Integer;
  74.     
  75.     retCode: OSErr;
  76.   
  77.   
  78.   PROCEDURE tryToProcessCheckBox(theDialog: DialogPtr; itemNo: Integer);
  79.   
  80.     VAR
  81.       itemType: Integer;
  82.       item: Handle;
  83.       box: Rect;
  84.       theValue: Integer;
  85.       
  86.   BEGIN
  87.     GetDItem(theDialog, itemNo, itemType, item, box);
  88.     IF itemType<>(ctrlItem+chkCtrl) THEN
  89.       Exit;
  90.     theValue := GetCtlValue(ControlHandle(item));
  91.     IF theValue<>0 THEN
  92.       theValue := 0
  93.     ELSE
  94.       theValue := 1;
  95.     SetCtlValue(ControlHandle(item), theValue);
  96.   END;  {tryToProcessCheckBox}
  97.   
  98.   
  99.   PROCEDURE getTextItem(theDialog: DialogPtr; itemNo: Integer; VAR text: Str255);
  100.   
  101.     VAR
  102.       itemType: Integer;
  103.       item: Handle;
  104.       box: Rect;
  105.       
  106.   BEGIN
  107.     GetDItem(theDialog, itemNo, itemType, item, box);
  108.     IF NOT ((itemType=editText) OR (itemType=statText)) THEN
  109.       Exit;
  110.     GetIText(item, text);
  111.   END;  {getTextItem}
  112.   
  113.   
  114.   FUNCTION checkButtonState(theDialog: DialogPtr; itemNo: Integer) : Boolean;
  115.   
  116.     VAR
  117.       itemType: Integer;
  118.       item: Handle;
  119.       box: Rect;
  120.       
  121.   BEGIN
  122.     GetDItem(theDialog, itemNo, itemType, item, box);
  123.     IF NOT ((itemType=(ctrlItem+chkCtrl))
  124.               OR (itemType=(ctrlItem+radCtrl))
  125.               OR (itemType=(ctrlItem+btnCtrl)))
  126.     THEN
  127.       BEGIN
  128.       checkButtonState := False;
  129.       Exit;
  130.       END;
  131.     checkButtonState := (GetCtlValue(ControlHandle(item)) = 1);
  132.   END;  {checkButtonState}
  133.   
  134.   
  135.   PROCEDURE decodeMainDialogState;
  136.   
  137.     CONST
  138.       cFilePrefix=5;
  139.       cDrvr=7;
  140.       cPdef0=8;
  141.       cPdef1=9;
  142.       cPdef4=10;
  143.       cPdef5=11;
  144.       cPack=12;
  145.       cInstallToSystem=13;
  146.       
  147.   BEGIN
  148.     WITH whatToDo DO
  149.       BEGIN
  150.         getTextItem(mainDialog, cFilePrefix, rFilePrefix);
  151.         rDrvr := checkButtonState(mainDialog, cDrvr);
  152.         rPdef0 := checkButtonState(mainDialog, cPdef0);
  153.         rPdef1 := checkButtonState(mainDialog, cPdef1);
  154.         rPdef4 := checkButtonState(mainDialog, cPdef4);
  155.         rPdef5 := checkButtonState(mainDialog, cPdef5);
  156.         rPack := checkButtonState(mainDialog, cPack);
  157.         rInstallToSystem := checkButtonState(mainDialog, cInstallToSystem);
  158.       END;  {WITH}
  159.   END;  {decodeMainDialogState}
  160.   
  161.   
  162.   FUNCTION determineFile : OSErr;
  163.   
  164.     VAR
  165.       where: Point;
  166.       dummy: Str255;
  167.       typeList: SFTypeList;
  168.       
  169.   BEGIN
  170.     where.v := 100;
  171.     where.h := 100;
  172.     typeList[0] := 'PRER';
  173.     typeList[1] := 'PRES';
  174.     SFGetFile(
  175.       where,
  176.       dummy,
  177.       NIL,
  178.       2,
  179.       typeList,
  180.       NIL,
  181.       whatToDo.rPrinterResourceFile
  182.     );
  183.     IF whatToDo.rPrinterResourceFile.good THEN
  184.       determineFile := noErr
  185.     ELSE
  186.       determineFile := bdNamErr;
  187.   END;  {determineFile}
  188.   
  189.   
  190.   { HomeResFile returns 0 when the resource is in the System file. }
  191.   { actualHomeResFile returns the actual reference number. }
  192.   FUNCTION actualHomeResFile(h: Handle) : Integer;
  193.     VAR
  194.       refNum: Integer;
  195.   BEGIN
  196.     refNum := HomeResFile(h);
  197.     IF refNum = 0 THEN
  198.       actualHomeResFile := actualSystemResFile
  199.     ELSE
  200.       actualHomeResFile := refNum;
  201.   END;  {actualHomeResFile}
  202.   
  203.   
  204.   PROCEDURE fileErrorAlert(theError: OSErr; whichFile: Str255);
  205.     VAR
  206.       resFileRefNum: Integer;
  207.       theErrorAsString: Str255;
  208.   BEGIN
  209.     resFileRefNum := CurResFile;
  210.     UseResFile(applicationResFile);
  211.     
  212.     NumToString(theError, theErrorAsString);
  213.     ParamText(theErrorAsString, whichFile, '', '');
  214.     IF StopAlert(fileErrorALRTId, NIL) = cancelButton THEN
  215.       ExitToShell;  {escape to Finder}
  216.     
  217.     UseResFile(resFileRefNum);
  218.   END;  {fileErrorAlert}
  219.   
  220.   
  221.   FUNCTION openPrinterResourceFile : OSErr;
  222.     LABEL
  223.       errorLabel;
  224.   BEGIN
  225.     retCode := SetVol(NIL, whatToDo.rPrinterResourceFile.vRefNum);
  226.     IF retCode <> noErr THEN
  227.       GOTO errorLabel;
  228.     printerResourceFileRefNum := OpenResFile(whatToDo.rPrinterResourceFile.fName);
  229.     IF printerResourceFileRefNum = -1 THEN
  230.       BEGIN
  231.       retCode := ResError;
  232.       GOTO errorLabel;
  233.       END;
  234.     
  235.     openPrinterResourceFile := noErr;
  236.     Exit;
  237.   
  238.   errorLabel:
  239.     fileErrorAlert(retCode, whatToDo.rPrinterResourceFile.fName);
  240.     openPrinterResourceFile := retCode;
  241.   END;  {openPrinterResourceFile}
  242.   
  243.   
  244.   PROCEDURE formFileName(prefix, suffix: Str255; VAR name: Str255);
  245.   BEGIN
  246.     name := prefix + suffix;
  247.   END;  {formFileName}
  248.   
  249.   
  250.   FUNCTION getResFromCurrentFile(theType: OSType; theId: Integer) : Handle;
  251.     VAR
  252.       h: Handle;
  253.   BEGIN
  254.     h := GetResource(theType, theId);
  255.     IF h<>NIL THEN
  256.       IF actualHomeResFile(h) <> CurResFile THEN
  257.         BEGIN
  258.         ReleaseResource(h);
  259.         h := NIL;
  260.         END;
  261.     getResFromCurrentFile := h;
  262.   END;  {getResFromCurrentFile}
  263.   
  264.   
  265.   FUNCTION replaceResource(
  266.     r: Handle;
  267.     theType: OSType;
  268.     theId: Integer;
  269.     theName: Str255;
  270.     newAttrs: Integer
  271.   ) : OSErr;
  272.     VAR
  273.       oldResource: Handle;
  274.       oldAttrs: Integer;
  275.   BEGIN
  276.     oldResource := GetResource(theType, theId);
  277.     IF oldResource <> NIL THEN
  278.       BEGIN
  279.       IF actualHomeResFile(oldResource) = CurResFile THEN
  280.         BEGIN
  281.         RmveResource(oldResource);
  282.         DisposHandle(oldResource);
  283.         END
  284.       ELSE
  285.         ReleaseResource(oldResource);
  286.       END;
  287.     
  288.     AddResource(r, theType, theId, theName);
  289.     IF ResError <> noErr THEN
  290.       BEGIN
  291.       replaceResource := ResError;
  292.       Exit;
  293.       END;
  294.     oldAttrs := GetResAttrs(r);
  295.     IF ResError <> noErr THEN
  296.       BEGIN
  297.       replaceResource := ResError;
  298.       Exit;
  299.       END;
  300.     newAttrs := (oldAttrs AND $FF83) OR (newAttrs AND $007C);
  301.     SetResAttrs(r, newAttrs);
  302.     IF ResError <> noErr THEN
  303.       BEGIN
  304.       replaceResource := ResError;
  305.       Exit;
  306.       END;
  307.     replaceResource := noErr;
  308.   END;  {replaceResource}
  309.   
  310.   
  311.   PROCEDURE processDrvr(suffix: Str255);
  312.     VAR
  313.       name: Str255;
  314.       sourceFileRefNum: Integer;
  315.       drvrHandle,
  316.       globalVariablesHandle: Handle;
  317.   BEGIN
  318.     formFileName(whatToDo.rFilePrefix, suffix, name);
  319.     sourceFileRefNum := OpenResFile(name);
  320.     IF sourceFileRefNum = -1 THEN
  321.       BEGIN
  322.       fileErrorAlert(ResError, name);
  323.       Exit;
  324.       END;
  325.     
  326.     drvrHandle := getResFromCurrentFile('DRVR', 2);
  327.     IF drvrHandle=NIL THEN
  328.       BEGIN
  329.       fileErrorAlert(ResError, name);
  330.       Exit;
  331.       END;
  332.     DetachResource(drvrHandle);
  333.     HNoPurge(drvrHandle);
  334.     
  335.     globalVariablesHandle := getResFromCurrentFile('DATA', -16320);
  336.     IF globalVariablesHandle=NIL THEN
  337.       BEGIN
  338.       fileErrorAlert(ResError, name);
  339.       Exit;
  340.       END;
  341.     DetachResource(globalVariablesHandle);
  342.     HNoPurge(globalVariablesHandle);
  343.     
  344.     CloseResFile(sourceFileRefNum);
  345.     IF ResError <> noErr THEN
  346.       fileErrorAlert(ResError, name);
  347.     
  348.     UseResFile(printerResourceFileRefNum);
  349.     retCode := replaceResource(drvrHandle, 'DRVR', resIdOwnedByPDEF, '.XPrint', (resPurgeable));
  350.     IF retCode <> noErr THEN
  351.       fileErrorAlert(retCode, whatToDo.rPrinterResourceFile.fName);
  352.     retCode := replaceResource(globalVariablesHandle, 'PREC', resIdOwnedByPDEF, 'Globals', (0));
  353.     IF retCode <> noErr THEN
  354.       fileErrorAlert(retCode, whatToDo.rPrinterResourceFile.fName);
  355.   END;  {processDrvr}
  356.  
  357.  
  358.   PROCEDURE processPdef(suffix: Str255; id:Integer);
  359.   
  360.     CONST
  361.       ourApplicationFileName='PRER_Builder';  {for error messages only}
  362.       
  363.     VAR
  364.       name: Str255;
  365.       sourceFileRefNum: Integer;
  366.       pdefHandle: Handle;
  367.       headerHandle: Handle;
  368.       resultHandle: Handle;
  369.   
  370.   BEGIN
  371.     formFileName(whatToDo.rFilePrefix, suffix, name);
  372.     sourceFileRefNum := OpenResFile(name);
  373.     IF sourceFileRefNum = -1 THEN
  374.       BEGIN
  375.       fileErrorAlert(ResError, name);
  376.       Exit;
  377.       END;
  378.     
  379.     pdefHandle := getResFromCurrentFile('PDEF', id);
  380.     IF pdefHandle=NIL THEN
  381.       BEGIN
  382.       fileErrorAlert(ResError, name);
  383.       Exit;
  384.       END;
  385.     DetachResource(pdefHandle);
  386.     HNoPurge(pdefHandle);
  387.     CloseResFile(sourceFileRefNum);
  388.     IF ResError <> noErr THEN
  389.       fileErrorAlert(ResError, name);
  390.     
  391.     UseResFile(printerResourceFileRefNum);
  392.     
  393.     { Add our jump table header to the beginning of resource. }
  394.     headerHandle := GetResource('HEAD', pdefCodeResourceHeaderHEADId);
  395.     IF headerHandle=NIL THEN
  396.       BEGIN
  397.       fileErrorAlert(ResError, ourApplicationFileName);
  398.       Exit;
  399.       END;
  400.     
  401.     resultHandle := NewHandle(GetHandleSize(headerHandle) + GetHandleSize(pdefHandle));
  402.     IF resultHandle=NIL THEN
  403.       BEGIN
  404.       fileErrorAlert(ResError, whatToDo.rPrinterResourceFile.fName);
  405.       Exit;
  406.       END;
  407.     
  408.     BlockMove(headerHandle^, resultHandle^, GetHandleSize(headerHandle));
  409.     BlockMove(
  410.       pdefHandle^,
  411.       Ptr(LongInt(resultHandle^) + GetHandleSize(headerHandle)),
  412.       GetHandleSize(pdefHandle)
  413.     );
  414.     
  415.     retCode := replaceResource(resultHandle, 'PDEF', id, '', (resPurgeable+resLocked));
  416.     IF retCode <> noErr THEN
  417.       fileErrorAlert(retCode, whatToDo.rPrinterResourceFile.fName);
  418.   END;  {processPdef}
  419.  
  420.  
  421.   PROCEDURE processPack(suffix: Str255);
  422.     TYPE
  423.       tCodeResourceHeader=
  424.         RECORD
  425.         rBranchToHex10: Integer;
  426.         rDeviceId: Integer;
  427.         rPACK: OSType;
  428.         rId4096: Integer;
  429.         rVersion: Integer;
  430.         rFlags: LongInt;
  431.         {start of driver code follows}
  432.         END;
  433.       tpCodeResourceHeader= ^tCodeResourceHeader;
  434.       thCodeResourceHeader= ^tpCodeResourceHeader;
  435.     VAR
  436.       name: Str255;
  437.       sourceFileRefNum: Integer;
  438.       r: Handle;
  439.   BEGIN
  440.     formFileName(whatToDo.rFilePrefix, suffix, name);
  441.     sourceFileRefNum := OpenResFile(name);
  442.     IF sourceFileRefNum = -1 THEN
  443.       BEGIN
  444.       fileErrorAlert(ResError, name);
  445.       Exit;
  446.       END;
  447.     
  448.     r := getResFromCurrentFile('PACK', resIdOwnedByPACK);
  449.     IF r=NIL THEN
  450.       BEGIN
  451.       fileErrorAlert(ResError, name);
  452.       Exit;
  453.       END;
  454.     DetachResource(r);
  455.     HNoPurge(r);
  456.     CloseResFile(sourceFileRefNum);
  457.     IF ResError <> noErr THEN
  458.       fileErrorAlert(ResError, name);
  459.     
  460.     UseResFile(printerResourceFileRefNum);
  461.     
  462.     WITH thCodeResourceHeader(r)^^ DO
  463.       BEGIN
  464.         rDeviceId := 3;  {should be 3 ???}
  465.         rVersion := 2;  {???}
  466.         rFlags := $0400E000;  {???}
  467.       END;  {WITH}
  468.     
  469.     retCode := replaceResource(r, 'PACK', resIdOwnedByPACK, 'Chooser intf', (resPurgeable));
  470.     IF retCode <> noErr THEN
  471.       fileErrorAlert(retCode, whatToDo.rPrinterResourceFile.fName);
  472.   END;  {processPack}
  473.  
  474.  
  475.   PROCEDURE installToSystem;
  476.     CONST
  477.       systemFileName= 'System';  {for error messages only}
  478.     VAR
  479.       nameHandle: StringHandle;
  480.   BEGIN
  481.     UseResFile(0);  {System file}
  482.     nameHandle := GetString(resIdOwnedByPDEF);
  483.     IF nameHandle=NIL THEN
  484.       BEGIN
  485.       fileErrorAlert(ResError, systemFileName);
  486.       Exit;
  487.       END;
  488.     SetString(nameHandle, whatToDo.rPrinterResourceFile.fName);
  489.     ChangedResource(Handle(nameHandle));
  490.     IF ResError<>noErr THEN
  491.       BEGIN
  492.       fileErrorAlert(ResError, systemFileName);
  493.       Exit;
  494.       END;
  495.     UpdateResFile(0);  {otherwise changes will be lost at application exit}
  496.     IF ResError<>noErr THEN
  497.       BEGIN
  498.       fileErrorAlert(ResError, systemFileName);
  499.       Exit;
  500.       END;
  501.   END;  {installToSystem}
  502.  
  503.  
  504. BEGIN
  505.   InitGraf(@thePort);
  506.   InitFonts;
  507.   FlushEvents(everyEvent, 0);
  508.   InitWindows;
  509.   InitMenus;
  510.   TEInit;
  511.   InitDialogs(NIL);
  512.   InitCursor;
  513.   
  514.   applicationResFile := CurResFile;
  515.   UseResFile(0);
  516.   actualSystemResFile := CurResFile;
  517.   UseResFile(applicationResFile);
  518.   
  519.   CouldAlert(fileErrorALRTId);  {make sure alert is always available in memory}
  520.   mainDialog := GetNewDialog(mainDLOGId, NIL, Pointer(-1));
  521.   IF mainDialog=NIL THEN
  522.     Exit;
  523.   
  524.   REPEAT
  525.     ModalDialog(NIL, itemHit);
  526.     tryToProcessCheckBox(mainDialog, itemHit);
  527.   UNTIL (itemHit=okButton) OR (itemHit=cancelButton);
  528.   IF itemHit=cancelButton THEN
  529.     Exit;
  530.   
  531.   decodeMainDialogState;  {sets whatToDo record according to dialog settings}
  532.   DisposDialog(mainDialog);
  533.   
  534.   IF determineFile<>noErr THEN  {sets printer resource file name & volume to whatToDo record}
  535.     Exit;
  536.   
  537.   retCode := openPrinterResourceFile;
  538.   IF retCode<>noErr THEN  {opens file and sets global RefNum}
  539.     BEGIN
  540.     fileErrorAlert(retCode, whatToDo.rPrinterResourceFile.fName);
  541.     Exit;
  542.     END;
  543.   
  544.   WITH whatToDo DO
  545.     BEGIN
  546.     IF rDrvr THEN processDrvr('DRVR');
  547.     IF rPdef0 THEN processPdef('PDEF0', 0);
  548.     IF rPdef1 THEN processPdef('PDEF1', 1);
  549.     IF rPdef4 THEN processPdef('PDEF4', 4);
  550.     IF rPdef5 THEN processPdef('PDEF5', 5);
  551.     IF rPack THEN processPack('PACK');
  552.     IF rInstallToSystem THEN installToSystem;
  553.     END;
  554.   
  555.   CloseResFile(printerResourceFileRefNum);  {changes will be updated}
  556.   IF ResError <> noErr THEN
  557.     fileErrorAlert(ResError, whatToDo.rPrinterResourceFile.fName);
  558.  
  559. END.
  560.